package match

import (
	"sanguo/cluster"
	"sanguo/node/common/com_type"
	"sanguo/node/common/orderMap"
	"sanguo/node/common/transaction"
	"sanguo/node/node_team"
	"sanguo/node/node_team/com"
	"sanguo/node/node_team/team"
	cs_msg "sanguo/protocol/cs/message"
	ss_rpc "sanguo/protocol/ss/rpc"
	"sanguo/rpc/createRoom"
	"time"

	"github.com/golang/protobuf/proto"
)

//处理匹配对象 分离队伍与角色
func disposeObjs(objs []*Object) (*team.Team, map[uint64]*RoleInfo) {
	var _team *team.Team = nil
	roles := map[uint64]*RoleInfo{}
	for _, obj := range objs {
		for _, r := range obj.Roles {
			roles[r.RoleID] = r
		}
		if obj.TeamID != 0 {
			_team = team.TeamMgr.GetTeam(obj.TeamID)
		}
	}

	return _team, roles
}

func CreatRoom(objs []*Object) {
	node_team.Infoln("Call CreateRoom---------->")
	node_battle, err := cluster.Random("battle")
	if nil != err {
		node_team.Debugln("no battle server")
		return
	}

	req := &ss_rpc.CreateRoomReq{
		BattlelevelID: proto.Int32(110606),
	}

	_team, roles := disposeObjs(objs)
	for _, r := range roles {
		_role := &ss_rpc.RoleInfo{
			UserID:  proto.String(r.UserID),
			RoleID:  proto.Uint64(r.RoleID),
			Game:    proto.String(r.Game.ToString()),
			Weapon1: proto.Int32(r.Weapon1),
			Weapon2: proto.Int32(r.Weapon2),
		}

		for id, val := range r.BattleAttrs {
			_role.BattleAttrs = append(_role.BattleAttrs, &ss_rpc.Attribute{
				Index: proto.Int32(id),
				Value: proto.Int32(val),
			})
		}
		/*
			for _, s := range r.Skills {
				_role.Skills = append(_role.Skills, &ss_rpc.Skill{
					SkillID:     proto.Int32(s.SkillID),
					SkillLevel:  proto.Int32(s.SkillLevel),
					SkillType:   proto.Int32(s.SkillType),
					SpecialStar: proto.Int32(s.SpecialStar),
				})
			}
		*/
		req.Role = append(req.Role, _role)
	}
	createRoom.AsynCall(node_battle, req, transaction.TransTimeoutMs, func(resp *ss_rpc.CreateRoomResp, err error) {
		if nil == err && resp.GetOk() == 0 {
			//返给客户端 队伍状态
			createRoomOk(_team, roles, resp, node_battle)
			node_team.Infoln("CreateRoomResp Ok", resp)
		} else {
			createRoomFail(_team, roles)
			node_team.Infoln("CreateRoomResp fail", err)
		}
	})
}

func createRoomOk(_team *team.Team, roles map[uint64]*RoleInfo, resp *ss_rpc.CreateRoomResp, node_battle cluster.PeerID) {
	toC := &cs_msg.MatchToC{
		MsgType:    cs_msg.MatchType(cs_msg.MatchType_Ok).Enum(),
		RoomID:     proto.Int64(resp.GetRoomID()),
		Token:      proto.String(resp.GetToken()),
		BattleAddr: proto.String(node_battle.ToString()),
	}

	room := &Room{
		RoomID:      resp.GetRoomID(),
		Token:       resp.GetToken(),
		BattleAddr:  node_battle,
		DestroyTime: time.Now().Unix() + resp.GetTime(),
		Roles:       map[uint64]*RoleInfo{},
	}
	MatchMgr.RoomMap[room.RoomID] = room

	for _, r := range roles {
		delete(MatchMgr.RoleToObj, r.RoleID)

		MatchMgr.RoleToRoom[r.RoleID] = room
		room.Roles[r.RoleID] = r

		com.SendToClient(r.Game, r.UserID, toC)
	}

	if _team != nil {
		_team.Status = com.TeamStatus_Battle
		_team.RoomID = room.RoomID

		intoTeam(_team, roles)
	} else { //没有队伍指定一个队长并创建一个队伍

		teamID, err := com.TeamGenID()
		if err == nil {
			newTeam := &team.Team{
				TeamID:        teamID,
				TeamType:      com_type.TeamType_Custom,
				Roles:         orderMap.NewOrderMap(),
				Header:        0,
				Status:        com.TeamStatus_Battle,
				NextHeartbeat: time.Now().Unix() + com.HeartBeatTimeout,
				AcceptApply:   com.AcceptApply_Request,
				ApplyRoles:    map[uint64]*team.ApplyRole{},
			}

			team.TeamMgr.AddTeam(newTeam)
			intoTeam(newTeam, roles)
		}
	}

}

func createRoomFail(_team *team.Team, roles map[uint64]*RoleInfo) {
	toC := &cs_msg.MatchToC{
		MsgType: cs_msg.MatchType(cs_msg.MatchType_Fail).Enum(),
	}

	for _, r := range roles {
		delete(MatchMgr.RoleToObj, r.RoleID)

		com.SendToClient(r.Game, r.UserID, toC)
	}

	if _team != nil {
		_team.Status = com.TeamStatus_Safe
	}

}

//将真人玩家加入到已有队伍
func intoTeam(_team *team.Team, roles map[uint64]*RoleInfo) {
	for _, role := range roles {
		rr := _team.GetRole(role.RoleID)
		if rr == nil {
			r := &team.Role{}
			r.RoleID = role.RoleID
			r.UserID = role.UserID
			r.Level = role.Level
			r.Name = role.Name
			r.Portrait = role.Portrait
			r.Outline = role.Outline
			r.Face = role.Face
			r.Hair = role.Hair
			r.HairColor = role.HairColor
			r.EyeColor = role.EyeColor
			r.Cloth = role.Cloth
			r.ClothColor = role.ClothColor
			r.Weapon1 = role.Weapon1
			r.Game = role.Game
			r.Status = com.RoleStatus_Online

			_team.AddRole(r)
			team.TeamMgr.RoleToTeam[r.RoleID] = _team
		}

		if _team.Header == 0 {
			_team.Header = role.RoleID
		}
	}
	team.UpdateTeamToClients(_team)

}
